package cartagows;

import java.io.FileInputStream;
import java.util.Properties;

import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.engine.ListenerManager;
import org.apache.axis2.transport.http.SimpleHTTPServer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cartago.Artifact;
import cartago.CartagoException;
import cartago.OPERATION;
import cartagows.wsframework.wscoordination.WSCoordinationParam;
import cartagows.wsframework.wscoordination.WSCoordinationWorker;

public class CWSServerArtifact extends Artifact{
    private static final Log log = LogFactory.getLog(SimpleHTTPServer.class);

    private ListenerManager listenerManager;
    private static String FILE_PROPERTY_NAME = "cartagows-config.properties";
    private static String CARTAGO_WS_BASE_PATH_PROPERTY = "cartagows_base_path";
    private static String REPOSITORY_PATH_PROPERTY = "repository_path";
    private static String CONF_PATH_PROPERTY = "conf_path";
    private static String CARTAGOWS_DEF_WSP_NAME = "cartagows_def_wsp_name";

    void init() throws Exception{
	}
	
	@OPERATION void startServer() throws CartagoException{
        try {
        	try {
            	Properties p = new Properties();
            	/* property file loading */
				p.load(new FileInputStream(FILE_PROPERTY_NAME));
				String basePath = p.getProperty(CARTAGO_WS_BASE_PATH_PROPERTY);
				String repoPath = p.getProperty(REPOSITORY_PATH_PROPERTY);
				String confPath = p.getProperty(CONF_PATH_PROPERTY);
				String defWspName = p.getProperty(CARTAGOWS_DEF_WSP_NAME);
				
				if (basePath!=null){
					CWSServiceManager.CARTAGO_WS_BASE_PATH = p.getProperty(CARTAGO_WS_BASE_PATH_PROPERTY);
				}
				if (repoPath!=null){
					CWSServiceManager.REPOSITORY_PATH = repoPath;
				} else if (basePath!=null){
					/* No REPOSITORY_PATH has been defined, we use the default one, appending the basePath if specified*/
					CWSServiceManager.REPOSITORY_PATH = CWSServiceManager.CARTAGO_WS_BASE_PATH + "/config/repository";
				}
				if (confPath!=null){
					CWSServiceManager.CONF_LOCATION = confPath;
				} else if (basePath!=null){
					/* No CONF_LOCATION has been defined, we use the default one, appending the basePath if specified*/
					CWSServiceManager.CONF_LOCATION = CWSServiceManager.CARTAGO_WS_BASE_PATH + "/config/conf.xml";
				}
				if (defWspName!=null){
					/* if a different name for the CArtAgO-WS enabled workspace has been provided we change the def value */
					CWSServiceManager.DEF_WSP_NAME = defWspName;
				}				
			} catch (Exception e) {
				log.info("[CARTAGO-WS Server] No cartagows-config.properties found, using default path for repository and service configuration.");
			}
        	/* Axis2 server configuration */
            ConfigurationContext configctx = 
            		ConfigurationContextFactory.createConfigurationContextFromFileSystem(CWSServiceManager.REPOSITORY_PATH, CWSServiceManager.CONF_LOCATION);
            listenerManager = new ListenerManager();
            listenerManager.init(configctx);
        	/* Axis2 server start*/
            listenerManager.start();
            log.info("[CARTAGO-WS Server] Started");
            WSCoordinationWorker wscoordWorker = new WSCoordinationWorker(WSCoordinationParam.WORKER_AGENT_DEF_NAME);
            wscoordWorker.start();
            log.info("[CARTAGO-WS Server] WS-Coordination support Started");
            log.info("[CARTAGO-WS Server] WS-AtomicTransaction support Started"); 
            
        } catch (Throwable t) {
            log.fatal("[CARTAGO-WS Server] Shutdown - Fatal error", t);
            if (listenerManager != null && !listenerManager.isStopped()){
            	try {
					listenerManager.stop();
				} catch (AxisFault e) {
					e.printStackTrace();
				}
            }
            throw new CartagoException("Error in starting CArtAgO-WS server.");
        }
    }

	@OPERATION void stopServer() throws CartagoException{
		if(listenerManager!=null){
			try {
				listenerManager.stop();
			} catch (AxisFault e) {
				throw new CartagoException();
			}
		}
	}
}